/**
 * @file midi_parser.h
 * @brief MIDI消息解析器 (支持MIDI 1.0, MIDI 2.0 UMP, BLE MIDI)
 * @date 2025-11-04
 */

#ifndef __MIDI_PARSER_H__
#define __MIDI_PARSER_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "midi_protocol.h"

/* Exported types ------------------------------------------------------------*/

/**
 * @brief MIDI消息结构体
 */
typedef struct {
    midi_message_type_e type;   /* 消息类型 */
    uint8_t channel;            /* MIDI通道 (0-15) */
    uint8_t note;               /* 音符号 (0x15-0x6C) */
    uint8_t velocity;           /* 力度 (0x00-0x7F, 7位) - MIDI 1.0 */
    uint16_t velocity_16;       /* 力度 (0x0000-0xFFFF, 16位) - MIDI 2.0 */
    uint8_t controller;         /* 控制器号 (用于CC消息) */
    uint8_t value;              /* 控制器值/数据值 (7位) */
} midi_message_t;

/* Exported functions prototypes ---------------------------------------------*/

/**
 * @brief 初始化MIDI解析器
 * @return 0成功, -1失败
 */
int midi_parser_init(void);

/**
 * @brief 解析MIDI数据
 * @param data 输入数据缓冲区
 * @param len 数据长度
 * @param msg 输出: 解析后的MIDI消息
 * @return 0成功, -1失败(无效数据或格式错误)
 * @note 支持MIDI 1.0字节流, MIDI 2.0 UMP, BLE MIDI格式
 */
int midi_parser_parse(uint8_t *data, uint8_t len, midi_message_t *msg);

/**
 * @brief 检查消息是否属于指定板号
 * @param msg MIDI消息
 * @param board_id 板号 (1-11)
 * @return true属于, false不属于
 * @note 对于广播消息(全部音符关, 温度警告)总是返回true
 */
bool midi_parser_is_for_board(midi_message_t *msg, uint8_t board_id);

/**
 * @brief 将MIDI音符转换为通道号 (0-7)
 * @param note MIDI音符号
 * @param board_id 当前板号
 * @return 通道号 (0-7), 如果不属于该板返回0xFF
 */
uint8_t midi_parser_note_to_channel(uint8_t note, uint8_t board_id);

#ifdef __cplusplus
}
#endif

#endif /* __MIDI_PARSER_H__ */

/******************************** 文件结束 *********************************/
